import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class BadugiPlayer extends JFrame implements ActionListener, Runnable, MouseListener {
	private static final long serialVersionUID = 1L;
	
	JFrame gui;
	JPanel helloPanel, mainPanel, buttonsPanel, drawCardsPanel, playerCards, dialogPanel, table;
	
	JPanel dealerButtonPanel, smallBlindPanel, bigBlindPanel;

	JButton button1, button2, button3, button4, button5, button6, button7;
	JButton connectButton, drawCardsButton, dontDrawCardsButton;
	JButton checkButton, betButton, raiseButton, callButton, foldButton, allInButton, dialogButton;

	JLabel hostIPLabel, hostPortLabel, playerNameLabel, dialogInfo;
	JLabel pot, yourBet, maxBet, potLabel, yourBetLabel, maxBetLabel, chipsAmountLabel;
	JLabel card1, card2, card3, card4;
	JLabel checkButtonLabel, betButtonLabel, raiseButtonLabel, callButtonLabel, allInButtonLabel, foldButtonLabel;
	JLabel activityLog, chipsAmount, gameResults;
	
	JLabel dealerButton, smallBlind, bigBlind;
	
	JLabel player1 = new JLabel(), player2 = new JLabel(), player3 = new JLabel(), player4 = new JLabel(), player5 = new JLabel(), player6 = new JLabel();
	
	JLabel player1bet = new JLabel();
	JLabel player2bet = new JLabel();
	JLabel player3bet = new JLabel();
	JLabel player4bet = new JLabel();
	JLabel player5bet = new JLabel();
	JLabel player6bet = new JLabel();
	
	JLabel[] players = new JLabel[]{player1,player2,player3,player4,player5,player6};
	JLabel[] playersBet = new JLabel[]{player1bet,player2bet,player3bet,player4bet,player5bet,player6bet};
	

	JCheckBox changeCard1;
	JCheckBox changeCard2;
	JCheckBox changeCard3;
	JCheckBox changeCard4;

	JTextField hostIP;
	JTextField hostPort;
	JTextField playerNameInput;
	JTextField dialogInput;

	Font labelFont = new Font("Helvetica", 1, 11);
	Font inputFont = new Font("Helvetica", 0, 13);
	Font cardFont = new Font("Helvetica", 1, 22);
	Font logFont = new Font("Ubuntu", 0, 10);
	Font buttonFont = new Font("Helvetica", 1, 13);
	Font buttonLabelFont = new Font("Helvetica", 0, 9);

	Cursor handCursor = Cursor.getPredefinedCursor(12);
	Color inputColor = new Color(0, 180, 255);
	Color inputBgColor = new Color(240, 250, 255);
	Color black30 = new Color(30, 30, 30);
	Color darkBlue = new Color(15, 25, 40);
	Color buttonBgColor = darkBlue;

	Socket socket = null;
	int playerID = 0;
	String playerName = "Guest";

	int numberOfPlayers = 0;
	int[][] allCoords = new int[][]{{73,191,64,76,160,20,297,20,399,76,390,191},
			{51,147,92,46,228,20,365,41,412,147}};
	int[] coords;
	
	private String action = "";
	private Socket playerSocket;
	private DataOutputStream writer;
	private DataInputStream reader;
	private boolean movesEnabled = true;
	
	boolean allowPainting = false;

	
	public BadugiPlayer(String host, int port, String playerNameTmp, boolean withDefaultSettings) {
		
		gui = new JFrame();
		gui.setLayout(null);
		gui.setBackground(new Color(20, 30, 55));
		gui.setTitle("Badugi Poker");
		gui.setResizable(false);
		gui.setDefaultCloseOperation(3);
		gui.setBounds(10, 10, 280, 250);

		if (withDefaultSettings) {
			
			/*
			 * Panel - user can set server's host, port and choose a nickname.
			 */
			helloPanel = new JPanel();
			helloPanel.setOpaque(true);
			helloPanel.setLayout(null);
			helloPanel.setBounds(0, 0, 400, 250);
			helloPanel.setBackground(new Color(20, 30, 55));
			gui.add(helloPanel);

			hostIPLabel = new JLabel();
			hostIPLabel.setOpaque(false);
			hostIPLabel.setText("Server IP address");
			hostIPLabel.setBounds(60, 10, 160, 20);
			hostIPLabel.setFont(labelFont);
			hostIPLabel.setForeground(Color.white);
			hostIPLabel.setHorizontalAlignment(JLabel.CENTER);
			helloPanel.add(hostIPLabel);

			hostIP = new JTextField("localhost");
			hostIP.setBounds(60, 30, 160, 20);
			hostIP.setBorder(null);
			hostIP.setFont(inputFont);
			hostIP.setForeground(inputColor);
			hostIP.setBackground(inputBgColor);
			hostIP.setHorizontalAlignment(JTextField.CENTER);
			helloPanel.add(hostIP);

			hostPortLabel = new JLabel("Server port");
			hostPortLabel.setOpaque(false);
			hostPortLabel.setBounds(60, 60, 160, 20);
			hostPortLabel.setFont(labelFont);
			hostPortLabel.setForeground(Color.white);
			hostPortLabel.setHorizontalAlignment(JLabel.CENTER);
			helloPanel.add(hostPortLabel);

			hostPort = new JTextField("4444");
			hostPort.setBounds(60, 80, 160, 20);
			hostPort.setBorder(null);
			hostPort.setFont(inputFont);
			hostPort.setForeground(inputColor);
			hostPort.setBackground(inputBgColor);
			hostPort.setHorizontalAlignment(JTextField.CENTER);
			helloPanel.add(hostPort);

			playerNameLabel = new JLabel("Your nickname");
			playerNameLabel.setOpaque(false);
			playerNameLabel.setBounds(60, 110, 160, 20);
			playerNameLabel.setFont(labelFont);
			playerNameLabel.setForeground(Color.white);
			playerNameLabel.setHorizontalAlignment(JLabel.CENTER);
			helloPanel.add(playerNameLabel);

			playerNameInput = new JTextField("Guest");
			playerNameInput.setBounds(60, 130, 160, 20);
			playerNameInput.setBorder(null);
			playerNameInput.setFont(inputFont);
			playerNameInput.setForeground(inputColor);
			playerNameInput.setBackground(inputBgColor);
			playerNameInput.setHorizontalAlignment(JTextField.CENTER);
			helloPanel.add(playerNameInput);

			connectButton = new JButton("Let me in!");
			connectButton.setOpaque(true);
			connectButton.setLayout(null);
			connectButton.addActionListener(this);
			connectButton.setBounds(90, 180, 100, 20);
			connectButton.setBackground(inputColor);
			connectButton.setForeground(Color.WHITE);
			connectButton.setFont(buttonFont);
			connectButton.setBorder(null);
			helloPanel.add(connectButton);

		}

		
		/*
		 * Main panel - visible, when player is connected to server.
		 */
		mainPanel = new JPanel();
		mainPanel.setLayout(null);
		mainPanel.setBackground(new Color(20, 30, 55));
		mainPanel.setVisible(false);
		mainPanel.setBounds(0, 0, 750, 510);
		gui.add(mainPanel);
		
		/*
		 * A panel with checkboxes and buttons to draw cards.
		 */
		drawCardsPanel = new JPanel();
		drawCardsPanel.setOpaque(false);
		drawCardsPanel.setLayout(null);
		drawCardsPanel.setVisible(false);
		drawCardsPanel.setBounds(34, 395, 460, 90);
		mainPanel.add(drawCardsPanel);
		
		changeCard1 = new JCheckBox();
		changeCard1.setOpaque(false);
		changeCard1.setBounds(0, 45, 30, 20);
		drawCardsPanel.add(changeCard1);

		changeCard2 = new JCheckBox();
		changeCard2.setOpaque(false);
		changeCard2.setBounds(70, 45, 30, 20);
		drawCardsPanel.add(changeCard2);

		changeCard3 = new JCheckBox();
		changeCard3.setOpaque(false);
		changeCard3.setBounds(140, 45, 30, 20);
		drawCardsPanel.add(changeCard3);

		changeCard4 = new JCheckBox();
		changeCard4.setOpaque(false);
		changeCard4.setBounds(210, 45, 30, 20);
		drawCardsPanel.add(changeCard4);

		drawCardsButton = new JButton("<html>Draw cards</html>");
		drawCardsButton.setLayout(null);
		drawCardsButton.setOpaque(true);
		drawCardsButton.setBounds(271, 0, 95, 20);
		drawCardsButton.addActionListener(this);
		drawCardsButton.addMouseListener(this);;
		drawCardsButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.white));
		drawCardsButton.setForeground(Color.white);
		drawCardsButton.setBackground(buttonBgColor);
		drawCardsButton.setFont(buttonFont);
		drawCardsButton.setCursor(handCursor);
		drawCardsPanel.add(drawCardsButton);

		dontDrawCardsButton = new JButton("<html>Don't draw cards</html>");
		dontDrawCardsButton.setLayout(null);
		dontDrawCardsButton.setOpaque(true);
		dontDrawCardsButton.setBounds(271, 25, 125, 20);
		dontDrawCardsButton.addActionListener(this);
		dontDrawCardsButton.addMouseListener(this);;
		dontDrawCardsButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.white));
		dontDrawCardsButton.setForeground(Color.white);
		dontDrawCardsButton.setBackground(buttonBgColor);
		dontDrawCardsButton.setFont(buttonFont);
		dontDrawCardsButton.setCursor(handCursor);
		drawCardsPanel.add(dontDrawCardsButton);

		
		/*
		 * A panel contains player's cards.
		 */
		playerCards = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				g.setColor(Color.white);
				
				for (int i = 0; i <= 3; i++) {
					g.fillRoundRect(10 + 70*i, 10, 65, 90, 10, 10);
				}
			}
		};
		playerCards.setOpaque(false);
		playerCards.setLayout(null);
		playerCards.setVisible(false);
		playerCards.setBounds(5, 340, 410, 100);
		mainPanel.add(playerCards);

		card1 = new JLabel();
		card1.setBounds(10, 10, 65, 90);
		card1.setHorizontalAlignment(JLabel.CENTER);
		card1.setFont(cardFont);
		playerCards.add(card1);
		
		card2 = new JLabel();
		card2.setBounds(80, 10, 65, 90);
		card2.setHorizontalAlignment(JLabel.CENTER);
		card2.setFont(cardFont);
		playerCards.add(card2);
		
		card3 = new JLabel();
		card3.setBounds(150, 10, 65, 90);
		card3.setHorizontalAlignment(JLabel.CENTER);
		card3.setFont(cardFont);
		playerCards.add(card3);
		
		card4 = new JLabel();
		card4.setBounds(220, 10, 65, 90);
		card4.setHorizontalAlignment(JLabel.CENTER);
		card4.setFont(cardFont);
		playerCards.add(card4);
		
		
		/* 
		 * A panel which displays all info about actions.
		 */
		dialogPanel = new JPanel();
		dialogPanel.setOpaque(false);
		dialogPanel.setLayout(null);
		dialogPanel.setBounds(15, 315, 480, 20);
		mainPanel.add(dialogPanel);

		dialogInput = new JTextField();
		dialogInput.setOpaque(true);
		dialogInput.setLayout(null);
		dialogInput.setBounds(382, 0, 40, 20);
		dialogInput.setVisible(false);
		dialogInput.setForeground(darkBlue);
		dialogInput.setHorizontalAlignment(JTextField.CENTER);
		dialogInput.setFont(new Font("Ubuntu", 1, 12));
		dialogInput.setBorder(null);
		dialogPanel.add(dialogInput);

		dialogInfo = new JLabel();
		dialogInfo.setBounds(0, 0, 380, 20);
		dialogInfo.setForeground(Color.white);
		dialogInfo.setText("Waiting for more players.");
		dialogInfo.setFont(new Font("Ubuntu", Font.PLAIN, 12));
		dialogPanel.add(dialogInfo);
		
		dialogButton = new JButton();
		dialogButton.setOpaque(true);
		dialogButton.setLayout(null);
		dialogButton.setBounds(425, 0, 35, 20);
		dialogButton.setText("OK");
		dialogButton.addActionListener(this);
		dialogButton.setVisible(false);
		dialogButton.setVerticalAlignment(JButton.CENTER);
		dialogButton.setBorder(null);
		dialogButton.setForeground(Color.white);
		dialogButton.setBackground(inputColor);
		dialogButton.setFont(buttonFont);
		dialogButton.setCursor(handCursor);
		dialogButton.addMouseListener(this);
		dialogPanel.add(dialogButton);

		
		/*
		 * Table panel.
		 */
		table = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				
				g.setColor(new Color(20,145,200));
				g.fillRoundRect(75,45,350,200,220,220);
				
				if (allowPainting) {
					g.setColor(new Color(255,130,0));
					
					for (int i = 0; i < numberOfPlayers; i++) {
						g.fillOval(coords[2*i], coords[2*i+1], 34,34);
					}
					
					g.setColor(new Color(0,0,0,190));
					
					for (int i = 0; i < numberOfPlayers; i++) {
						g.fillRoundRect(coords[2*i]-24, coords[2*i+1]+36, 80, 30, 10, 10);
					}
				}
			}
		};
		table.setLayout(null);
		table.setOpaque(true);
		table.setBounds(0, 0, 500, 300);
		table.setBackground(new Color(20,40,70));
		mainPanel.add(table);

		potLabel = new JLabel("Pot:");
		potLabel.setOpaque(true);
		potLabel.setLayout(null);
		potLabel.setBackground(darkBlue);
		potLabel.setForeground(Color.white);
		potLabel.setBounds(0, 264, 125, 16);
		potLabel.setVerticalAlignment(JLabel.BOTTOM);
		potLabel.setFont(new Font("Ubuntu", 1, 9));
		potLabel.setBorder(BorderFactory.createMatteBorder(0, 10, 0, 0, darkBlue));
		table.add(potLabel);

		pot = new JLabel("$0");
		pot.setOpaque(true);
		pot.setLayout(null);
		pot.setBackground(darkBlue);
		pot.setForeground(Color.white);
		pot.setBounds(0, 280, 125, 20);
		pot.setFont(new Font("Ubuntu", 0, 12));
		pot.setBorder(BorderFactory.createMatteBorder(0, 10, 0, 0, darkBlue));
		pot.setVerticalAlignment(JLabel.TOP);
		table.add(pot);

		chipsAmountLabel = new JLabel("Your chips:");
		chipsAmountLabel.setOpaque(true);
		chipsAmountLabel.setLayout(null);
		chipsAmountLabel.setBackground(darkBlue);
		chipsAmountLabel.setForeground(Color.white);
		chipsAmountLabel.setBounds(125, 264, 125, 16);
		chipsAmountLabel.setVerticalAlignment(JLabel.BOTTOM);
		chipsAmountLabel.setFont(new Font("Ubuntu", 1, 9));
		table.add(chipsAmountLabel);
		
		chipsAmount = new JLabel("$0");
		chipsAmount.setOpaque(true);
		chipsAmount.setLayout(null);
		chipsAmount.setBackground(darkBlue);
		chipsAmount.setForeground(Color.white);
		chipsAmount.setBounds(125, 280, 125, 20);
		chipsAmount.setFont(new Font("Ubuntu", 0 , 12));
		chipsAmount.setVerticalAlignment(JLabel.TOP);
		table.add(chipsAmount);

		yourBetLabel = new JLabel("Your total bet:");
		yourBetLabel.setOpaque(true);
		yourBetLabel.setLayout(null);
		yourBetLabel.setBackground(darkBlue);
		yourBetLabel.setForeground(Color.white);
		yourBetLabel.setBounds(250, 264, 125, 16);
		yourBetLabel.setVerticalAlignment(JLabel.BOTTOM);
		yourBetLabel.setFont(new Font("Ubuntu", 1, 9));
		table.add(yourBetLabel);

		yourBet = new JLabel("$0");
		yourBet.setOpaque(true);
		yourBet.setLayout(null);
		yourBet.setBackground(darkBlue);
		yourBet.setForeground(Color.white);
		yourBet.setBounds(250, 280, 125, 20);
		yourBet.setFont(new Font("Ubuntu", 0 , 12));
		yourBet.setVerticalAlignment(JLabel.TOP);;
		table.add(yourBet);

		maxBetLabel = new JLabel("Call (max bet):");
		maxBetLabel.setOpaque(true);
		maxBetLabel.setLayout(null);
		maxBetLabel.setBackground(darkBlue);
		maxBetLabel.setForeground(Color.white);
		maxBetLabel.setBounds(375, 264, 125, 16);
		maxBetLabel.setVerticalAlignment(JLabel.BOTTOM);
		maxBetLabel.setFont(new Font("Ubuntu", 1, 9));
		table.add(maxBetLabel);

		maxBet = new JLabel("$0");
		maxBet.setOpaque(true);
		maxBet.setLayout(null);
		maxBet.setBackground(darkBlue);
		maxBet.setForeground(Color.white);
		maxBet.setBounds(375, 280, 125, 20);
		maxBet.setFont(new Font("Ubuntu", 0, 12));
		maxBet.setVerticalAlignment(JLabel.TOP);;
		table.add(maxBet);
		
		/*
		 * Display a 'delaer button' next to its holder.
		 */
		dealerButtonPanel = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				g.setColor(Color.orange);
				g.fillOval(0,0,14,14);
			}
		};
		dealerButtonPanel.setOpaque(false);
		dealerButtonPanel.setLayout(null);
		dealerButtonPanel.setBorder(null);
		dealerButtonPanel.setBounds(0, 0, 14, 14);
		
		dealerButton = new JLabel("D");
		dealerButton.setLayout(null);
		dealerButton.setBounds(0,0,14,14);
		dealerButton.setFont(new Font("Helvetica", 1, 8));
		dealerButton.setHorizontalAlignment(JLabel.CENTER);
		dealerButton.setVerticalAlignment(JLabel.CENTER);
		dealerButtonPanel.add(dealerButton);
		
		
		/*
		 * Displays a 'small blind' next to its holder.
		 */
		smallBlindPanel = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				g.setColor(new Color(175,210,230));
				g.fillOval(0,0,14,14);
			}
		};
		smallBlindPanel.setOpaque(false);
		smallBlindPanel.setLayout(null);
		smallBlindPanel.setBorder(null);
		smallBlindPanel.setBounds(0, 0, 14, 14);

		smallBlind = new JLabel("S");
		smallBlind.setLayout(null);
		smallBlind.setBounds(0,0,14,14);
		smallBlind.setFont(new Font("Helvetica", 1, 8));
		smallBlind.setHorizontalAlignment(JLabel.CENTER);
		smallBlind.setVerticalAlignment(JLabel.CENTER);
		smallBlind.setForeground(new Color(35,70,125));
		smallBlindPanel.add(smallBlind);
		
		
		/*
		 * Displays a 'big blind' next to its holder.
		 */
		bigBlindPanel = new JPanel() {
			public void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				g.setColor(new Color(175,210,230));
				g.fillOval(0,0,14,14);
			}
		};
		bigBlindPanel.setOpaque(false);
		bigBlindPanel.setLayout(null);
		bigBlindPanel.setBorder(null);
		bigBlindPanel.setBounds(0, 0, 14, 14);

		bigBlind = new JLabel("B");
		bigBlind.setLayout(null);
		bigBlind.setBounds(0,0,14,14);
		bigBlind.setFont(new Font("Helvetica", 1, 8));
		bigBlind.setHorizontalAlignment(JLabel.CENTER);
		bigBlind.setVerticalAlignment(JLabel.CENTER);
		bigBlind.setForeground(new Color(35,70,125));
		bigBlindPanel.add(bigBlind);
		
		
		/*
		 * Panel contains all action buttons:
		 * check, bet, call, raise, all-in, fold.
		 */
		buttonsPanel = new JPanel();
		buttonsPanel.setOpaque(false);
		buttonsPanel.setLayout(null);
		buttonsPanel.setVisible(false);
		buttonsPanel.setBounds(320, 350, 155, 210);
		mainPanel.add(buttonsPanel);

		checkButton = new JButton("Check");
		checkButton.addActionListener(this);
		checkButton.addMouseListener(this);
		checkButton.setBounds(0, 0, 70, 20);
		checkButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
		checkButton.setForeground(Color.WHITE);
		checkButton.setCursor(handCursor);
		checkButton.setFont(buttonFont);
		checkButton.setOpaque(true);
		checkButton.setBackground(buttonBgColor);
		buttonsPanel.add(checkButton);

		betButton = new JButton("Bet");
		betButton.addActionListener(this);
		betButton.addMouseListener(this);
		betButton.setBounds(0, 35, 70, 20);
		betButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
		betButton.setForeground(Color.WHITE);
		betButton.setCursor(handCursor);
		betButton.setFont(buttonFont);
		betButton.setOpaque(true);
		betButton.setBackground(buttonBgColor);
		buttonsPanel.add(betButton);

		callButton = new JButton("Call");
		callButton.addActionListener(this);
		callButton.addMouseListener(this);
		callButton.setBounds(0, 70, 70, 20);
		callButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
		callButton.setForeground(Color.WHITE);
		callButton.setCursor(handCursor);
		callButton.setFont(buttonFont);
		callButton.setOpaque(true);
		callButton.setBackground(buttonBgColor);
		buttonsPanel.add(callButton);

		raiseButton = new JButton("Raise");
		raiseButton.addActionListener(this);
		raiseButton.addMouseListener(this);
		raiseButton.setBounds(85, 0, 70, 20);
		raiseButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
		raiseButton.setForeground(Color.WHITE);
		raiseButton.setCursor(handCursor);
		raiseButton.setFont(buttonFont);
		raiseButton.setOpaque(true);
		raiseButton.setBackground(buttonBgColor);
		buttonsPanel.add(raiseButton);

		allInButton = new JButton("All-in");
		allInButton.addActionListener(this);
		allInButton.addMouseListener(this);
		allInButton.setBounds(85, 35, 70, 20);
		allInButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
		allInButton.setForeground(Color.WHITE);
		allInButton.setCursor(handCursor);
		allInButton.setFont(buttonFont);
		allInButton.setOpaque(true);
		allInButton.setBackground(buttonBgColor);
		buttonsPanel.add(allInButton);

		foldButton = new JButton("Fold");
		foldButton.addActionListener(this);
		foldButton.addMouseListener(this);
		foldButton.setBounds(85, 70, 70, 20);
		foldButton.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.WHITE));
		foldButton.setForeground(Color.WHITE);
		foldButton.setCursor(handCursor);
		foldButton.setFont(buttonFont);
		foldButton.setOpaque(true);
		foldButton.setBackground(buttonBgColor);
		buttonsPanel.add(foldButton);

		/*
		 * A JLabel contains history of the game.
		 */
		activityLog = new JLabel();
		activityLog.setOpaque(true);
		activityLog.setBounds(500, 0, 250, 500);
		activityLog.setForeground(Color.white);
		activityLog.setBackground(darkBlue);
		activityLog.setVerticalAlignment(JLabel.TOP);
		activityLog.setFont(logFont);
		mainPanel.add(activityLog);
		
		/*
		 * A JLabel contains all cards when game is over.
		 */
		gameResults = new JLabel();
		gameResults.setOpaque(false);
		gameResults.setForeground(Color.white);
		gameResults.setBounds(20,300,300,188);
		gameResults.setFont(new Font("Ubuntu", 0, 12));
		gameResults.setBorder(BorderFactory.createMatteBorder(0,20,0,0,new Color(0,0,0,0)));
				
		gui.setVisible(true);
				
		if (!withDefaultSettings) {
			playerName = playerNameTmp;
			connectToServer(host, port);
		}
	}

	
	private void connectToServer(String host, int port) {
		try {
			playerSocket = new Socket(host, port);

			System.out.println("\n > Successfully connected to server :)\n");

			reader = new DataInputStream(playerSocket.getInputStream());
			writer = new DataOutputStream(playerSocket.getOutputStream());

			new Thread(this).start();
			
			mainPanel.setVisible(true);
			
		} catch (IOException e) {
			System.out.println("\n > Cannot connect to '" + host + "' (port: " + port + ")\n");
			System.exit(-1);
		}
	}
	
	
	private void sendRequest(String message) {
		try {
			writer.writeUTF(message);
		} catch (IOException e) {
			System.out.println(e);
		}
	}
	
	
	public void actionPerformed(ActionEvent evt) {
		if (evt.getSource() == dialogButton) {
			
			if ((action != "") || (action != null)) {
				dialogInfo.setText(null);
				dialogButton.setVisible(false);
				dialogInput.setVisible(false);
				
				if ((action.equalsIgnoreCase("bet")) || (action.equalsIgnoreCase("raise"))) {
					try {
						int amount = Integer.parseInt(dialogInput.getText());
						
						if (amount <= 0)
							dialogInfo.setText("<html><span style=\"color:red\"><b>Error:</b> minimum value is $1.</span></html>");
						else
							sendRequest(action + " " + dialogInput.getText());
						
					} catch (Exception e) {
						dialogInfo.setText("<html><span style=\"color:red\"><b>Error:</b> value must be an integer.</span></html>");
					}
					
					dialogInput.setText("");
				} else
					sendRequest(action);
			}
		} else if (evt.getSource() == checkButton) {
			action = "check";

			if (dialogButton.isVisible() != true)
				dialogButton.setVisible(true);
			
			if (dialogInput.isVisible() == true)
				dialogInput.setVisible(false);
			
			dialogInfo.setText("<html>Are you sure, you want to play <b>Check</b>?</html>");

		} else if (evt.getSource() == betButton) {
			
			action = "bet";
			
			if (dialogButton.isVisible() != true)
				dialogButton.setVisible(true);

			if (dialogInput.isVisible() != true)
				dialogInput.setVisible(true);
			
			dialogInfo.setText("<html>First bet amount:</html>");
			
		} else if (evt.getSource() == raiseButton) {
			
			action = "raise";

			if (dialogButton.isVisible() != true)
				dialogButton.setVisible(true);

			if (dialogInput.isVisible() != true)
				dialogInput.setVisible(true);

			dialogInfo.setText("<html>How much do you want to <b>raise</b>?</html>");
			
		} else if (evt.getSource() == callButton) {
			
			action = "call";

			if (dialogButton.isVisible() != true)
				dialogButton.setVisible(true);

			if (dialogInput.isVisible() == true) {
				dialogInput.setVisible(false);
			}

			dialogInfo.setText("<html>Are you sure, you want to play <b>call</b>?</html>");
			
		} else if (evt.getSource() == allInButton) {
			
			action = "allIn";

			if (dialogButton.isVisible() != true)
				dialogButton.setVisible(true);
			
			if (dialogInput.isVisible() == true) 
				dialogInput.setVisible(false);

			dialogInfo.setText("<html>Are you sure, you want to play <b>all-in</b>?</html>");
			
		} else if (evt.getSource() == foldButton) {
			
			action = "fold";

			if (dialogButton.isVisible() != true) 
				dialogButton.setVisible(true);

			if (dialogInput.isVisible() == true)
				dialogInput.setVisible(false);

			dialogInfo.setText("<html>Are you sure, you want to leave the game? :(</html>");
			
		} else if (evt.getSource() == drawCardsButton) {
			
			String cardsToChange = "";
			
			if (changeCard1.isSelected())
				cardsToChange += " 1";
			
			if (changeCard2.isSelected()) 
				cardsToChange += " 2";

			if (changeCard3.isSelected())
				cardsToChange += " 3";

			if (changeCard4.isSelected()) 
				cardsToChange += " 4";

			if (cardsToChange != "")
				sendRequest("drawMyCards" + cardsToChange);

			changeCard1.setSelected(false);
			changeCard2.setSelected(false);
			changeCard3.setSelected(false);
			changeCard4.setSelected(false);
			
		} else if (evt.getSource() == dontDrawCardsButton) {
			
			sendRequest("dontDrawMyCards");
			drawCardsPanel.setVisible(false);
			
		} else if (evt.getSource() == connectButton) {
			
			String host = hostIP.getText();
			int port;

			try {
				port = Integer.parseInt(hostPort.getText());
			} catch (Exception e) {
				port = 4444;
			}

			playerName = playerNameInput.getText();

			connectToServer(host, port);

			helloPanel.setVisible(false);
			
		} else {
			sendRequest(evt.getActionCommand());
		}
	}


	public void run() {
		try {
			while (true) {
				String response = reader.readUTF();
				
				if (response == null)
					continue;
					
				String[] tab = response.split(" ");
				String cmd = tab[0];

				if (cmd.equalsIgnoreCase("numberOfPlayers")) {
					numberOfPlayers = Integer.parseInt(tab[1]);
					setCoords(numberOfPlayers);
					
					allowPainting = true;
					
					table.repaint();
					drawTableComponents();
					
				} else if (cmd.equalsIgnoreCase("welcomeInGame")) {
					System.out.println("Welcome");
					sendRequest("numberOfPlayers");
					sendRequest("returnMyID");
					sendRequest("setPlayerName " + playerName);
					sendRequest("returnMyCards");
					sendRequest("returnMyChips");
					
				} else if (cmd.equalsIgnoreCase("yourID")) {
					
					playerID = Integer.parseInt(tab[1]);

					gui.setSize(750, 510);
					
				} else if (cmd.equalsIgnoreCase("yourName")) {
					
					playerName = tab[1];
					players[playerID-1].setText(playerName);
							
					gui.setTitle("Badugi Poker | " + playerName);
					
				} else if (cmd.equalsIgnoreCase("yourCards")) {
					
					JLabel[] cardLabel = new JLabel[] { card1, card2, card3, card4 };

					for (int i = 0; i < cardLabel.length; i++) {
						String[] card = convertCardToShape(tab[(i + 1)]);

						if (card[1].equalsIgnoreCase("Red")) {
							cardLabel[i].setForeground(Color.RED);
						} else {
							cardLabel[i].setForeground(Color.BLACK);
						}

						cardLabel[i].setText("<html>" + card[0] + "</html>");
					}
					
				} else if (cmd.equalsIgnoreCase("yourChips")) {
					chipsAmount.setText("$" + tab[1]);
					
				} else if (cmd.equalsIgnoreCase("chipsWithAward")) {
					chipsAmount.setText("$" + tab[1]);
					
				} else if (cmd.equalsIgnoreCase("actionOk")) {
					
					if (action.equalsIgnoreCase("fold")) {
						playerCards.setVisible(false);
						dialogInfo.setText("You left the game :(");
						
					} else {
						sendRequest("returnMyChips");
					}
					
					action = "";
					
				} else if (cmd.equalsIgnoreCase("actionError")) {
					
					buttonsPanel.setVisible(true);

					if (action.equals("allIn")) {
						action = "All-in";
					} else {
						action = action.substring(0, 1).toUpperCase() + action.substring(1);
					}

					dialogInfo.setText("<html><span style=\"color:red\"><b>Error:</b> you can't play <i>" + action + "</i>, because you have not enough chips.</span></html>");
					dialogInfo.setVisible(true);
					action = "";
					
				} else if (cmd.equalsIgnoreCase("drawCardsSuccess")) {
					
					drawCardsPanel.setVisible(false);
					dialogInfo.setText("<html><i>Waiting for other players.</i></html>");
					dialogInfo.setVisible(true);
					
				} else if (cmd.equalsIgnoreCase("dontDrawCardsSuccess")) {
					
					drawCardsPanel.setVisible(false);
					dialogInfo.setText("<html><i>Waiting for other players.</i></html>");
					dialogInfo.setVisible(true);

				} else if (cmd.equalsIgnoreCase("startOfTheGame")) {
					
					addActivityEvent(response.substring(14));

					sendRequest("returnMyChips");
					playerCards.setVisible(true);
					dialogInfo.setText("");
					
				} else if (cmd.equalsIgnoreCase("startData")) {
					
					if (tab[2].equalsIgnoreCase(playerID + "")) {
						addActivityEvent("<span style=\"color:#666666\">&nbsp; First move is yours.</span>");

						if (checkButton.isEnabled() != Boolean.parseBoolean(tab[11]))
							checkButton.setEnabled(Boolean.parseBoolean(tab[11]));

						if (betButton.isEnabled() != Boolean.parseBoolean(tab[12])) 
							betButton.setEnabled(Boolean.parseBoolean(tab[12]));

						if (callButton.isEnabled() != Boolean.parseBoolean(tab[13]))
							callButton.setEnabled(Boolean.parseBoolean(tab[13]));

						if (raiseButton.isEnabled() != Boolean.parseBoolean(tab[14]))
							raiseButton.setEnabled(Boolean.parseBoolean(tab[14]));

						if (allInButton.isEnabled() != Boolean.parseBoolean(tab[15]))
							allInButton.setEnabled(Boolean.parseBoolean(tab[15]));

						buttonsPanel.setVisible(true);
					} else {
						addActivityEvent("<span style=\"color:#666666\">&nbsp; First move: <b>" + tab[4] + "</b>.</span>");
					}
						
					if (tab[8].equals(playerID + ""))
						yourBet.setText("$" + tab[7]);
					else if (tab[10].equals(playerID + ""))
						yourBet.setText("$" + tab[9]);
					
					playersBet[Integer.parseInt(tab[8])-1].setText("$" + tab[7]);
					playersBet[Integer.parseInt(tab[10])-1].setText("$" + tab[9]);
					
					table.add(dealerButtonPanel);
					table.add(smallBlindPanel);
					table.add(bigBlindPanel);
					
					redrawBlinds(Integer.parseInt(tab[6]), Integer.parseInt(tab[8]), Integer.parseInt(tab[10]));
					
				} else if (cmd.equalsIgnoreCase("nextPlayerMove")) {
					
					if ((tab[1].equalsIgnoreCase(playerID + "")) && (movesEnabled)) {
						addActivityEvent("<span style=\"color:#666666\">&nbsp; Your turn.</span>");

						if (checkButton.isEnabled() != Boolean.parseBoolean(tab[3]))
							checkButton.setEnabled(Boolean.parseBoolean(tab[3]));

						if (betButton.isEnabled() != Boolean.parseBoolean(tab[4]))
							betButton.setEnabled(Boolean.parseBoolean(tab[4]));

						if (callButton.isEnabled() != Boolean.parseBoolean(tab[5]))
							callButton.setEnabled(Boolean.parseBoolean(tab[5]));

						if (raiseButton.isEnabled() != Boolean.parseBoolean(tab[6]))
							raiseButton.setEnabled(Boolean.parseBoolean(tab[6]));

						if (allInButton.isEnabled() != Boolean.parseBoolean(tab[7]))
							allInButton.setEnabled(Boolean.parseBoolean(tab[7]));

						buttonsPanel.setVisible(true);
					} else {
						addActivityEvent("<span style=\"color:#666666\">&nbsp; Next move: <b>" + tab[2] + "</b>.</span>");

						if (buttonsPanel.isVisible() == true)
							buttonsPanel.setVisible(false);

					}
					
				} else if (cmd.equalsIgnoreCase("endOfRound")) {
					
					addActivityEvent("<span style=\"color:orange\">&nbsp; End of round (" + tab[1] + "/7)</span>");
					
					if (Integer.parseInt(tab[1]) % 2 != 0)
						buttonsPanel.setVisible(false);
					
				} else if (cmd.equalsIgnoreCase("newRound")) {
					
					dialogInfo.setText("");


					if (Integer.parseInt(tab[1]) % 2 == 0) {
						addActivityEvent("<span style=\"color:orange\"><b>NEW ROUND - Draw your cards</b> (" + tab[1] + "/7)</span>");

						if (movesEnabled) {
							drawCardsPanel.setVisible(true);
						}
					} else {
						addActivityEvent("<span style=\"color:orange\"><b>NEW ROUND - Bet</b> (" + tab[1] + "/7)</span>");
						
						maxBet.setText("$0");
						
						for (int i = 0; i < numberOfPlayers; i++)
							if (!playersBet[i].getText().contains("All-in") && !playersBet[i].getText().contains("Fold"))
								playersBet[i].setText("");
					}
					
				} else if (cmd.equalsIgnoreCase("disableMoves")) {
					
					movesEnabled = false;
					
				} else if (cmd.equalsIgnoreCase("scaleDownGui")) {
					
					gui.setSize(750, 322);
					
				} else if (cmd.equalsIgnoreCase("endOfGame")) {
					
					dialogInfo.setText("");

					if (buttonsPanel.isVisible())
						buttonsPanel.setVisible(false);
					
					addActivityEvent("<span style=\"color:orange\"><b>END OF THE GAME!</b></span>");
					
				} else if (cmd.equalsIgnoreCase("gameResult")) {
					yourBet.setText("$0");
					maxBet.setText("$0");
					pot.setText("$0");
					
					
					if (tab[1].equalsIgnoreCase("winner")) {
						if (tab[2].equals(playerID + "")) {
							sendRequest("returnMyAward");
							addActivityEvent("<span style=\"color: #84D700\"><b>&nbsp; &#9733; You won the game :)</b></span>");
						} else {
							yourBet.setText("$0");
							addActivityEvent("<span style=\"color: #84D700\"><b>&nbsp; &#9733; Winner: " + tab[3] + "</b></span>");
						}
						
					} else
						addActivityEvent("<span style=\"color: #FCFF0A\"><i>&nbsp; It's a tie...</i></span>");

				} else if (cmd.equalsIgnoreCase("tableUpdate")) {

					if (tab[1].equals("potAndMaxBet")) {
						pot.setText("$" + tab[2]);
						maxBet.setText("$" + tab[3]);
						
					} else if (tab[1].equals("yourBet")) {
						yourBet.setText("$" + tab[2]);
						
					} else if (tab[1].equals("newPlayer")) {
						players[Integer.parseInt(tab[2])-1].setText(tab[3]);

					} else if (tab[1].equals("allCurrentPlayers")) {
						for (int i = 2; i+1 < tab.length; i+=2) {
							players[Integer.parseInt(tab[i])-1].setText(tab[i+1]);
						}
						
					} else if (tab[1].equals("playerBet")) {
						playersBet[Integer.parseInt(tab[2])-1].setText("$" + tab[3]);
					
					} else if (tab[1].equals("allIn")) {
						playersBet[Integer.parseInt(tab[2])-1].setText("<html><span style=\"color:yellow\">All-in</span></html>");
					
					} else if (tab[1].equals("fold")) {
						playersBet[Integer.parseInt(tab[2])-1].setText("<html><span style=\"color:red\">Fold</span></html>");
					
					} else if (tab[1].equals("dealerAndBlinds")) {
						redrawBlinds(Integer.parseInt(tab[2]), Integer.parseInt(tab[3]), Integer.parseInt(tab[4]));
					
					} else if (tab[1].equals("showCards")) {
						String str = "";
						
						if (playerCards.isVisible())
							playerCards.setVisible(false);
						
						for (int i = 2; i+4 < tab.length; i+=5) {	
							
							if (tab[i] == null || tab[i].equals("null"))
								continue;
							
							str += "<div style=\"padding-bottom:3px\">";
							str += "<div style=\"font-size:7px\">"+tab[i]+"</div>";
							
							for (int j = 1; j <= 4; j++) {
								String[] card = convertCardToShape(tab[i+j]);
								
								if (card[1].equalsIgnoreCase("black"))
									card[1] = "white";
								
								str += "&nbsp; <b><span style=\"color:" + card[1] + "\">" + card[0] + "</span></b>";
							}
							
							str += "</div>";
						}
						
						mainPanel.add(gameResults);
						gameResults.setText("<html>" + str + "</html>");
						
					}
					
				} else {
					addActivityEvent(response);
				}

			}
		} catch (IOException e) {
			System.out.println(e);
		}
	}

	private void addActivityEvent(String event) {
		String str = activityLog.getText();

		if (str.length() > 13) {
			str = str.substring(6, str.length() - 7);
		}
		
		str = "<div style=\"padding: 2px 3px; width:494px; border-bottom:1px dashed #233750;\">" + event + "</div>" + str;
		activityLog.setText("<html>" + str + "</html>");
	}

	private String[] convertCardToShape(String card) {
		String[] cards = card.split("-");
		String shape = "";

		try {
			if (cards[2].equals("Spade"))
				shape = "&spades;";
			else if (cards[2].equals("Club"))
				shape = "&clubs;";
			else if (cards[2].equals("Diamond"))
				shape = "&diams;";
			else
				shape = "&hearts;";
		
			switch (Integer.parseInt(cards[0])) {
				case 1: {
					cards[0] = "A"; break; }
				case 11: {
					cards[0] = "J"; break; }
				case 12: {
					cards[0] = "Q"; break; }
				case 13: {
					cards[0] = "K"; break; }
			}
			
		} catch (Exception e) {
			System.out.println("\n > Cannot display a card. Oh, God! Why?\n");
		}

		return new String[] {cards[0] + shape, cards[1]};
	}
		
	void setCoords(int num) {
		coords = new int[2*num];
		int index = 0;
		
		for (int i = (6-num%2)-num; i <= num+(5-num%2); i++) {
			coords[index] = allCoords[num%2][i];
						
			index += 1;
		}
	}
	
	void drawTableComponents() {
		for (int i = 0; i < numberOfPlayers; i++) {
			players[i] = new JLabel();
			players[i].setBounds(coords[2*i]-24, coords[2*i+1]+36, 80, 14);
			players[i].setForeground(Color.white);
			players[i].setFont(new Font("Ubuntu", Font.BOLD, 9));
			players[i].setHorizontalAlignment(JLabel.CENTER);
			players[i].setVerticalAlignment(JLabel.CENTER);
			table.add(players[i]);
			
			playersBet[i] = new JLabel();
			playersBet[i].setBounds(coords[2*i]-24, coords[2*i+1]+50, 80, 14);
			playersBet[i].setForeground(new Color(230,230,230));
			playersBet[i].setFont(new Font("Ubuntu", Font.PLAIN, 10));
			playersBet[i].setHorizontalAlignment(JLabel.CENTER);
			playersBet[i].setVerticalAlignment(JLabel.CENTER);
			table.add(playersBet[i]);
		}
	}
	
	
	void redrawBlinds(int dealer, int small, int big) {
		dealer -= 1;
		small -= 1;
		big -= 1;
		
		dealerButtonPanel.setBounds(coords[2 * dealer] + 58, coords[2 * dealer + 1] + 36, 14, 14);
		smallBlindPanel.setBounds(coords[2*small] + 58, coords[2 * small + 1] + 51, 14, 14);
		bigBlindPanel.setBounds(coords[2 * big] + 58, coords[2 * big + 1] + 51, 14, 14);
	}
	
	
	public void mouseClicked(MouseEvent e) {}
	public void mousePressed(MouseEvent e) {}
	public void mouseReleased(MouseEvent e) {}

	
	public void mouseEntered(MouseEvent e) {
		Object src = e.getSource();
		
		if (src == checkButton && checkButton.isEnabled()) {			
			checkButton.setBackground(Color.white);
			checkButton.setForeground(darkBlue);
			
		} else if (src == betButton && betButton.isEnabled()) {			
			betButton.setBackground(Color.white);
			betButton.setForeground(darkBlue);
			
		} else if (src == callButton && callButton.isEnabled()) {			
			callButton.setBackground(Color.white);
			callButton.setForeground(darkBlue);
			
		} else if (src == raiseButton && raiseButton.isEnabled()) {			
			raiseButton.setBackground(Color.white);
			raiseButton.setForeground(darkBlue);
			
		} else if (src == allInButton && allInButton.isEnabled()) {			
			allInButton.setBackground(Color.white);
			allInButton.setForeground(darkBlue);
			
		} else if (src == foldButton && foldButton.isEnabled()) {			
			foldButton.setBackground(Color.white);
			foldButton.setForeground(darkBlue);
		} else if (src == drawCardsButton && drawCardsButton.isEnabled()) {			
			drawCardsButton.setBackground(Color.white);
			drawCardsButton.setForeground(darkBlue);
		} else if (src == dontDrawCardsButton && dontDrawCardsButton.isEnabled()) {			
			dontDrawCardsButton.setBackground(Color.white);
			dontDrawCardsButton.setForeground(darkBlue);
		} else if (src == dialogButton) {
			dialogButton.setBackground(new Color(0,150,210));
		}
	}

	
	public void mouseExited(MouseEvent e) {
		Object src = e.getSource();
		
		if (src == checkButton && checkButton.isEnabled()) {			
			checkButton.setBackground(buttonBgColor);
			checkButton.setForeground(Color.white);
			
		} else if (src == betButton && betButton.isEnabled()) {			
			betButton.setBackground(buttonBgColor);
			betButton.setForeground(Color.white);
			
		} else if (src == callButton && callButton.isEnabled()) {			
			callButton.setBackground(buttonBgColor);
			callButton.setForeground(Color.white);
			
		} else if (src == raiseButton && raiseButton.isEnabled()) {			
			raiseButton.setBackground(buttonBgColor);
			raiseButton.setForeground(Color.white);
			
		} else if (src == allInButton && allInButton.isEnabled()) {			
			allInButton.setBackground(buttonBgColor);
			allInButton.setForeground(Color.white);
			
		} else if (src == foldButton && foldButton.isEnabled()) {			
			foldButton.setBackground(buttonBgColor);
			foldButton.setForeground(Color.white);

		} else if (src == drawCardsButton && drawCardsButton.isEnabled()) {			
			drawCardsButton.setBackground(buttonBgColor);
			drawCardsButton.setForeground(Color.white);

		} else if (src == dontDrawCardsButton && dontDrawCardsButton.isEnabled()) {			
			dontDrawCardsButton.setBackground(buttonBgColor);
			dontDrawCardsButton.setForeground(Color.white);
			
		} else if (src == dialogButton) {
			dialogButton.setBackground(inputColor);
		}
	}

	
	public static void main(String[] args) {
		String playerName = null, host;
		boolean defaultSettings = true;
		int port;

		try {
			host = args[0];
			port = Integer.parseInt(args[1]);

			if (args.length > 2) {
				if (args[2].length() > 12)
					args[2] = args[2].substring(0,12);
				
				playerName = args[2];
			}
			
			defaultSettings = false;
			
		} catch (Exception e) {
			port = 4444;
			host = "localhost";
		}

		
		new BadugiPlayer(host, port, playerName, defaultSettings);
	}
}